/*******************************************************************************
 * The MOSES project, model based software engineering of networked embedded systems.
 * 
 * Copyright (C) 2010-2013, University of Applied Sciences Wildau,
 * Telematics Research Group, http://www.tm.th-wildau.de/research-group
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 * 
 * Contributors:
 *     University of Applied Sciences Wildau - initial API and implementation
 * 
 * If you are interested in a commercial license please contact us via 
 * e-mail: ralf.vandenhouten@th-wildau.de.
 ******************************************************************************/
package de.thwildau.tm.moses.abnf.generator;

import java.util.Iterator;

import de.thwildau.tm.moses.abnf.generator.model.AbnfElementField;
import de.thwildau.tm.moses.abnf.generator.model.impl.AbnfElementFieldImpl;
import de.thwildau.tm.moses.abnf.generator.model.impl.AbnfRuleClassImpl;
 

/**
 * Utility class to save the state of the read-method for the code generator. This state
 * class is necessary because the sequences of the generated read-invocations can differ, 
 * depending on the elements that needs to read.
 * <p>
 * This class holds the current and the next element that is generated into the read-method
 * and whether the real read invocation has been done on that element.
 * </p>
 * <p>
 * This class is a workaround for an Iterator. Actually the {@link AbnfElementFieldImpl} object
 * can be returned as an {@link Iterator} from the {@link AbnfRuleClassImpl}, but the Iterator
 * Interface does not support to retrieve the current element.
 * </p>
 *
 * @author Thomas Kistel
 * @version $Revision: 762 $
 *
 */
/* package */ class AbnfReadState {
    
    private boolean isFirst = false;
    private boolean wasCurrentElementRead = false;
    private boolean wasNextElementRead = false;
    private AbnfElementField current;
    private AbnfElementField next;
    
    public AbnfReadState(AbnfReadState lastState, AbnfElementField current, AbnfElementField next) {
        this.current = current;
        this.next = next;
        if(lastState == null) {
            this.isFirst = true;
        } else {
            wasCurrentElementRead = lastState.wasNextElementRead;
        }
    }
    
    /**
     * Returns whether this is the first element of the object that is read.
     * 
     * @return whether this is the first element of the object
     */
    public boolean isFirst() {
        return isFirst;
    }
    
    /**
     * Returns whether the current element was already read in previous steps ({@code true}).
     * Returns {@code false} if not and need to be read.
     * 
     * @return whether the current element was already read in previous steps 
     */
    public boolean wasNextElementRead() {
        return wasNextElementRead;
    }
    
    public boolean wasCurrentElementRead() {
        return wasCurrentElementRead;
    }

    /**
     * Returns the current ABNF element that is read. Never returns {@code null}.
     * 
     * @return the current ABNF element that is read, never {@code null}
     */
    public AbnfElementField getCurrent() {
        return current;
    }
    
    /**
     * Returns the next ABNF element that will be read. Returns {@code null}, if
     * the current is the last element that is read.
     * 
     * @return the next ABNF element that will be read, maybe {@code null}
     */
    public AbnfElementField getNext() {
        wasNextElementRead = true;
        return next;
    }    
}
